<template>
  <div class="dynamic_form_item" :style="props.question.state.style">
    <a-form-item :name="props.question.key">
      <template v-slot:label v-if="props.question.label">
        <label for="">{{ props.question.label }}</label>
        <a-tooltip v-if="props.question.state.tipText" :key="props.question.label" :title="props.question.state.tipText">
          <i class="iconfont" :style="{ marginLeft: '8px' }" :class="props.question.state.tipIconClassName"></i>
        </a-tooltip>
      </template>
      <div class="custom_table" :style="{ width: props.question.state.widthTable || '100%' }">
        <div class="dynamic_screen_right" v-if="props.question.state.isScreen">
          <div class="dynamic_screen_wrap">
            <div class="dynamic_screen_list">
              <a-checkbox-group v-model:value="screenValue" @change="setColumns">
                <div class="dynamic_screen_item" v-for="item in screenList">
                  <a-checkbox :value="item.key || item.type">{{ item.title }}</a-checkbox>
                </div>
              </a-checkbox-group>
            </div>
          </div>
          <i class="iconfont icon-setting"></i>
        </div>
        <a-form-item-rest>
          <a-table
            :columns="props.question.state.columns"
            :rowKey="props.question.state.rowKey || 'id'"
            :scroll="props.question.state.scroll || {}"
            :data-source="props.question.value"
            :bordered="!props.question.state.hideBorder"
            :pagination="props.question.state.pagination || false"
            :row-selection="rowSelection"
          >
            <template #headerCell="{ column }">
              <template v-if="column.required">
                <span><i class="custom_icon_required">*</i>{{ column.title }}</span>
              </template>
              <a-tooltip v-if="column.tipText" placement="top" :title="column.tipText">
                <i class="iconfont" :class="column.icon" :style="{ marginLeft: '8px' }"></i>
              </a-tooltip>
            </template>
            <template #bodyCell="{ column, index, text, record }">
              <template v-if="column.type === 'operation'">
                <div class="editable-row-operations">
                  <template v-for="(item, zIndex) in column.handle">
                    <span v-if="isHidden(record, item)" @click="tableControl(record, item, index)">
                      <a>{{ item.text }}</a>
                    </span>
                  </template>
                </div>
              </template>
              <template v-else-if="column.type === 'index'">
                <span>{{ index + 1 }}</span>
              </template>
              <a-form-item-rest v-else>
                <div :class="{ err_line: ruleHint[index] && ruleHint[index].includes(column.key) }">
                  <template v-if="column.type === 'select'">
                    <a-select
                      v-if="!(showKeys[index] && showKeys[index][column.key])"
                      v-model:value="props.question.value[index][column.key]"
                      allow-clear
                      :showSearch="!column.state?.showSearch"
                      :disabled="isDisabled(column.disabled, record) || props.question.disabled"
                      :options="column.options"
                      :optionFilterProp="column.state?.optionFilterProp || 'value'"
                      :placeholder="column.placeholder || '请选择'"
                      @click="selectClick(props.question.value[index][column.key], column, index)"
                      @change="selectChange(props.question.value[index][column.key], column, index)"
                    ></a-select>
                  </template>
                  <template v-else-if="column.type === 'tree-select'">
                    <a-tree-select
                      v-if="!(showKeys[index] && showKeys[index][column.key])"
                      v-model:value="props.question.value[index][column.key]"
                      allow-clear
                      show-search
                      :placeholder="column.placeholder || '请选择'"
                      tree-default-expand-all
                      tree-node-filter-prop="label"
                      :multiple="column.state.treeMultiple"
                      :disabled="isDisabled(column.disabled, record) || props.question.disabled"
                      :tree-data="column.options"
                      :tree-checkable="column.state.treeCheckable"
                      @change="selectChange(props.question.value[index][column.key], column, index)"
                    ></a-tree-select>
                  </template>
                  <template v-else-if="column.type === 'cascader'">
                    <a-cascader
                    @change="(value: any, selectedOptions: any) => cascaderChange(value, selectedOptions, { question: props.question, column, index })"
                      :expand-trigger="column.state.trigger || 'hover'"
                      :changeOnSelect="column.state.changeOnSelect ? true : false"
                      :multiple="column.state.multiple || false"
                      :fieldNames="column.state.names"
                      :options="column.options"
                      v-model:value="props.question.value[index][column.key]"
                      :disabled="isDisabled(column.disabled, record) || props.question.disabled"
                    ></a-cascader>
                  </template>
                  <template v-else-if="column.type === 'time'">
                    <a-time-picker
                      v-if="!(showKeys[index] && showKeys[index][column.key])"
                      :disabled="isDisabled(column.disabled, record) || props.question.disabled"
                      v-model:value="props.question.value[index][column.key]"
                      :format="column.format || 'HH:mm:ss'"
                      :valueFormat="column.valueFormat || 'HH:mm:ss'"
                      @change="deleteRule(column.key, index)"
                    ></a-time-picker>
                  </template>
                  <template v-else-if="column.type === 'date'">
                    <a-date-picker
                      v-if="!(showKeys[index] && showKeys[index][column.key])"
                      :disabled="isDisabled(column.disabled, record) || props.question.disabled"
                      v-model:value="props.question.value[index][column.key]"
                      :valueFormat="column.format || 'YYYY-MM-DD HH:mm:ss'"
                      :picker="'date'"
                      @change="deleteRule(column.key, index)"
                    ></a-date-picker>
                  </template>
                  <!-- 开关 -->
                  <template v-else-if="column.type === 'switch'">
                    <a-switch
                      v-if="!(showKeys[index] && showKeys[index][column.key])"
                      :disabled="isDisabled(column.disabled, record) || props.question.disabled"
                      v-model:checked="props.question.value[index][column.key]"
                      @change="serveEvent(props.question.value[index][column.key], column, index)"
                    />
                  </template>
                  <!-- 跳转路由 -->
                  <template v-else-if="column.type === 'event'">
                    <span class="cursor text-primary" @click="tableControl(record, column.state, index)">{{ props.question.value[index][column.key] }}</span>
                  </template>
                  <template v-else-if="column.type === 'number'">
                    <a-input-number
                      v-if="!(showKeys[index] && showKeys[index][column.key])"
                      :disabled="isDisabled(column.disabled, record) || props.question.disabled"
                      v-model:value="props.question.value[index][column.key]"
                      @change="serveEvent(props.question.value[index][column.key], column, index)"
                      :maxlength="column.state?.maxlength"
                    />
                  </template>
                  <!-- 本地自定义slot -->
                  <template v-else-if="column.type === 'custom'">
                    <slot :name="column.key" :index="index" :text="text" :record="record"></slot>
                  </template>
                  <!-- 数据字典过滤器 -->
                  <template v-else-if="column.type === 'dictionary'">
                    <!-- tag标签 -->
                    <template v-if="column.tag && typeof column.tag === 'object'">
                      <a-tag :color="column.tag[props.question.value[index][column.key]]">{{ dictionaryFn(column.state, props.question.value[index][column.key]) }}</a-tag>
                    </template>
                    <template v-if="column.colors && typeof column.colors === 'object'">
                      <span :style="{ color: column.colors[props.question.value[index][column.key]?.value] }">{{ dictionaryFn(column.state, props.question.value[index][column.key]) }}</span>
                    </template>
                    <template v-else>
                      {{ dictionaryFn(column.state, props.question.value[index][column.key]) }}
                    </template>
                  </template>
                  <template v-else-if="column.type === 'input'">
                    <a-input
                      v-if="!(showKeys[index] && showKeys[index][column.key])"
                      :disabled="isDisabled(column.disabled, record) || props.question.disabled"
                      v-model:value="props.question.value[index][column.key]"
                      :placeholder="column.placeholder || '请输入'"
                      :maxlength="column.state?.maxlength || 9999"
                      :auto-size="{ minRows: 3, maxRows: 3 }"
                      @change="serveEvent(props.question.value[index][column.key], column, index)"
                    />
                  </template>
                  <template v-else-if="column.type === 'number'">
                    <a-input-number
                      v-if="!(showKeys[index] && showKeys[index][column.key])"
                      :disabled="isDisabled(column.disabled, record) || props.question.disabled"
                      v-model:value="props.question.value[index][column.key]"
                      :placeholder="column.placeholder || '请输入'"
                      @change="serveEvent(props.question.value[index][column.key], column, index)"
                      @blur="sumBlur(record, column, index)"
                    />
                  </template>
                  <template v-else>
                    <span v-if="!(showKeys[index] && showKeys[index][column.key])">
                      <template v-if="column.state && column.state.sumKeys">
                        {{ autoSum(record, column, index) }}
                      </template>
                      <template v-else>
                        {{ props.question.value[index][column.key] }}
                      </template>
                    </span>
                  </template>
                  <div class="err_hint">
                    {{ column.prompt || '格式错误' }}
                  </div>
                </div>
              </a-form-item-rest>
            </template>
          </a-table>
        </a-form-item-rest>
        <div class="group_add" v-if="props.question.state.isAdd" @click="addItem()">{{ props.question.state.text || '添加' }}</div>
      </div>
    </a-form-item>
  </div>
</template>

<script setup lang="ts">
import { $Http } from '@/config/service/http';
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { computed, createVNode, getCurrentInstance, nextTick, onMounted, reactive, ref, watch } from 'vue';
import { QuestionBase } from '../../../question-base';
import { getDictionaryList } from '@/utils/dictionary';
import XEUtils from 'xe-utils';
import { CUSTOMEVENTSERVE, CUSTOMSDELETESERVE, CUSTOMSELECTCLICKSERVE, CUSTOMSELECTSERVE, DYNAMICLAYERFORM, DYNAMICLAYERTABLE, DYNAMICLOCALTABLE, INFOSERVE } from '@/mixins/subject/subject-types';
import { assignParams, paramsData } from '@/components/public-template/publicMethod';
import { dictionaryFn, timeFilter } from '@/filters/index';
import { isHidden } from '@/utils';
import { Subscription } from 'rxjs';
import { filter } from 'rxjs/operators';
import { formInfoStore } from '@/store/modules/form';
import localDictionary from '@/filters/dictionary';

//subject变量
let $subscribeSub: Subscription;

let props = defineProps<{ question: QuestionBase<any>; formData: any }>();
const emit = defineEmits(['update:formData']);

const { proxy }: any = getCurrentInstance();

watch(
  () => props.question.value,
  (val) => {
    emit('update:formData', val);
  },
  { flush: 'sync' }
);

const keys = ref([]);
const showKeys = ref([]);
const ruleHint = ref({});

//多选
let rowSelection: any = reactive(null);
const selectedRows = ref<any[]>([]);
let selectedRowKeys: any = reactive([]);

//分页参数

let pagination: any = reactive({
  totalCount: 0,
  pageNumber: 1,
  pageSize: 10,
  pageSizeOptions: ['25', '50', '100']
});

onMounted(() => {
  init();
  subWatch();
});

//筛选
const screenList = ref([]);
const screenValue = ref([]);
const setColumns = (arr = null) => {
  if (arr) {
    screenValue.value = arr;
  }
  props.question.state.columns = screenList.value.filter((res) => screenValue.value.includes(res.key || res.type));
};

//自动计算
// const combinedNums = computed(() => (field: any) => {
//   return contentTableParam.dataSource.reduce((prev: number, next: { [x: string]: any }) => {
//     return prev + next[field]
//   }, 0)
// })
const sumBlur = (record, column, index) => {};
const autoSum = computed(() => {
  return (record, column, index) => {
    let sum = 0;
    column.state &&
      column.state.sumKeys.forEach((key) => {
        if (record[key]) {
          sum += +record[key];
        }
      });
    props.question.value[index][column.key] = sum;
    return props.question.value[index][column.key];
  };
});

//禁用重复选项
const setDisabled = (column) => {
  if (column.state && column.state.onRepeat) {
    //开启不重复选项
    let keys = props.question.value.map((res: any) => res[column.key]);
    keys &&
      column.options &&
      column.options.forEach((item: any) => {
        item.disabled = keys.includes(item.value) ? true : false;
      });
  }
};

//选择方法
const onSelectChange = (oldSelectedRowKeys: any, oldSelectedRows: any) => {
  selectedRowKeys.value = props.question.state.selectedRowKeys = oldSelectedRowKeys;
  selectedRows.value = oldSelectedRows;
  console.log('看下选中', props.question);
};
//默认选中
const autoSelection = (oldSelectedRowKeys: any) => {
  selectedRowKeys.value = oldSelectedRowKeys;
  rowSelection.selectedRowKeys = selectedRowKeys.value;
};

//监听动态表单数据完成
const subWatch = () => {
  $subscribeSub = proxy.$NotificationFormSub
    .getParams()
    .pipe(filter((res: any) => res !== 0))
    .subscribe((item: any) => {
      try {
        if (item.key === INFOSERVE) {
          init();
        }
      } catch (error) {}
    });
};

const init = () => {
  if (props.question.state.pagination) {
    pagination = Object.assign(pagination, props.question.state.pagination);
  }
  if (!props.question.value) {
    props.question.value = [];
  }
  //type:多选/单选=> checkbox/radio,集体参数可见https://antdv.com/components/table-cn#rowSelection
  if (props.question.state.rowSelection) {
    console.log('初始化开始', props.question);
    rowSelection = computed(() => {
      return Object.assign(
        {
          onChange: onSelectChange,
          selectedRowKeys: selectedRowKeys.value
        },
        props.question.state.rowSelection
      );
    });
  }
  if (props.question.state.columns) {
    //筛选
    screenList.value = XEUtils.clone(props.question.state.columns, true);
    screenValue.value = screenList.value.map((res) => res.key || res.type);
    console.log('screenValue');

    keys.value = props.question.state.columns.filter((res) => res.key).map((res) => res.key);
    showKeys.value = XEUtils.clone(props.question.value, true) || [];
    showKeys.value &&
      showKeys.value.forEach((item) => {
        for (const key in item) {
          item[key] = false;
        }
      });
    props.question.state.columns.forEach((column) => {
      if (column.type === 'select' && column.state) {
        if (column.state.url) {
          getDictionaryList(column.state, (res) => {
            nextTick(() => {
              column.options = res;
            });
          });
        } else if (column.state.filterName) {
          const formStore = formInfoStore();
          let dictionary = formStore.getDictionary;
          let dicObj: any = dictionary[column.state.filterName] || localDictionary[column.state.filterName];
          let arr: any = [];
          for (const key in dicObj) {
            if (dicObj.hasOwnProperty(key)) {
              arr.push({
                label: dicObj[key],
                value: props.question.state.valueType === 'string' ? key + '' : +key
              });
            }
          }
          column.options = arr;
        }
        setDisabled(column);
      } else if (column.type === 'tree-select' && column.state) {
        if (column.state.url) {
          getDictionaryList(column.state, (res) => {
            // 树形下拉，是否只能选择叶子
            // eslint-disable-next-line no-inner-declarations
            function reData(list: any[]) {
              if (!list) return;
              return list.map((item: any) => {
                item.disabled = !!item.children;
                if (item.children) reData(item.children);
                return item;
              });
            }
            if (column.state.leafOnly) {
              res = reData(res);
            }
            nextTick(() => {
              column.options = res;
            });
          });
        }
      } else if (column.type === 'cascader') {
        // console.log(cascader,'==================99999');
        
        if (column.state?.url) {
          let params = Object.assign({}, column.state.params || {});
          proxy.$Http.api(column.state.url, params, column.state.protType ? column.state.protType : 'get').then((data: any) => {
            column.options = data.data;
          });
        }
        console.log(column.options,'==================99999');
      }
    });
  }
  pagination.totalCount = props.question.value?.length;
  // listData =  props.question.value.slice(0, pagination.pageSize);
  console.log('看下自定义table数据', props.question.value);
};

//table按钮
const tableControl = (data: any, part: any, index: number) => {
  console.log('看下index：', index);
  switch (part.type) {
    case 'delete':
      deteleItem(index, data);
      break;
    case 'url':
      proxy.$goTo(part.url, assignParams(data, part));
      break;
    case 'router':
      proxy.$goTo(part.url, part.params);
      break;
    case 'hint':
      pubHint(data, part);
      break;
    case 'layerFrom': //弹层from
      if (part.params) {
        let params = assignParams(data, part);
        part.config.params = params;
      }
      if (part.configId) {
        part.config.id = data[part.configId];
      }
      proxy.$NotificationPubSub.pushParams({
        key: DYNAMICLAYERFORM,
        value: {
          config: part.config,
          form: part.form,
          data
        }
      });
      break;
    case 'layerTable': //弹层table
      if (part.params) {
        let params = assignParams(data, part);
        part.config.params = params;
      }
      proxy.$NotificationPubSub.pushParams({
        key: DYNAMICLAYERTABLE,
        value: {
          tables: part.table,
          form: part.form,
          config: part.config,
          index: part.index || 0,
          name: part.name || ''
        }
      });
      break;
    case 'local':
      //把数据传给本地处理
      proxy.$NotificationPubSub.pushParams({ key: DYNAMICLOCALTABLE, value: { data, part, index } });
      break;
    default:
  }
};

//删除
const deteleItem = (index, record) => {
  console.log('🚀 ~ file: input-customTable.component.vue:457 ~ deteleItem ~ record:', record, props);
  Modal.confirm({
    title: '删除提示',
    autoFocusButton: null,
    icon: createVNode(ExclamationCircleOutlined),
    content: '是否确定删除你所选择的一条数据，确定后将直接删除？',
    okText: '确认',
    centered: true,
    cancelText: '取消',
    onOk() {
      if (props.question.state.deleteUrl && record.id) {
        $Http.api(props.question.state.deleteUrl, { id: record.id }, props.question.state.protType ? props.question.state.protType : 'delete').then((res) => {
          if (res) {
            message.success('删除成功！');
            props.question.value.splice(index, 1);
            showKeys.value.splice(index, 1);
            pagination.totalCount = props.question.value?.length;
            proxy.$NotificationFormSub.pushParams({
              key: CUSTOMSDELETESERVE,
              value: {
                data: record,
                index,
                value: props.question.value
              }
            });
          }
        });
      } else {
        props.question.value.splice(index, 1);
        showKeys.value.splice(index, 1);
        pagination.totalCount = props.question.value?.length;
        proxy.$NotificationFormSub.pushParams({
          key: CUSTOMSDELETESERVE,
          value: {
            data: record,
            index,
            value: props.question.value
          }
        });
      }
      // 重置禁用
      const columns = props.question.state.columns;
        columns.forEach((column: any) => {
          if (column.state?.onRepeat) {
            setDisabled(column);
          }
        });
    }
  });
};

//新增
const addItem = () => {
  let obj = {};
  let obj2 = {};
  keys.value.map((key) => {
    if (props.question.state.default) {
      obj[key] = props.question.state.default[key];
    } else {
      obj[key] = null;
    }
    obj2[key] = false;
  });
  if (!props.question.value) {
    props.question.value = [];
  }
  props.question.value.push(obj);
  showKeys.value.push(obj2);
  pagination.totalCount = props.question.value?.length;
  proxy.$NotificationFormSub.pushParams({
    key: CUSTOMEVENTSERVE,
    value: {
      key: 'add',
      value: props.question.value,
      name: 'add',
      index: props.question.value.length - 1
    }
  });
};

//公用弹层提示
const pubHint = (data: any, part: any) => {
  if (part.state && part.state.hintData) {
    Modal.confirm({
      title: part.state.hintData.title,
      autoFocusButton: null,
      icon: createVNode(ExclamationCircleOutlined),
      okText: '确定',
      cancelText: '取消',
      centered: true,
      content: part.state.hintData.content ? part.state.hintData.content : '',
      onOk: () => {
        let params: any = paramsData(data, part);
        proxy.$Http.api(part.url, params, part.postType ? part.postType : 'post', part.urlParema ? true : false).then((data: any) => {
          message.success('操作成功!');
          if (part.state.callBack) {
            proxy.$NotificationPubSub.pushParams({ key: 'DynamicTableControlHint', value: { data, part } });
          }
        });
      },
      onCancel: () => {}
    });
  }
};

//点击事件
const selectClick = (value, column, index) => {
  proxy.$NotificationFormSub.pushParams({
    key: CUSTOMSELECTCLICKSERVE,
    value: {
      key: column.key,
      value,
      name: column?.name || column?.state?.name || '',
      index
    }
  });
};

//控制显示隐藏
const selectChange = (value, column, index) => {
  deleteRule(column.key, index);
  if (column.changeOptions) {
    let arr = column.changeOptions[value || 'default'];
    arr.forEach((item: any) => {
      if (item.option === 'hidden') {
        props.question.value[index][item.key] = item.value === true ? undefined : props.question.value[index][item.key];
        showKeys.value[index][item.key] = item.value; //控制隐藏
      }
    });
  }
  setDisabled(column);

  //把服务传出
  let data: any = column.options.find((res) => res.value === value);
  proxy.$NotificationFormSub.pushParams({
    key: CUSTOMSELECTSERVE,
    value: {
      key: column.key,
      value,
      name: column?.name || column?.state?.name || '',
      index,
      data
    }
  });
  //控制同行数据,自动赋值value
  if (column.autoFillValue) {
    autoValues(data, column.autoFillValue, index);
  }
};

//自动填充值
const autoValues = (data, params, index) => {
  console.log('进来了吗', data, params, index);
  for (const key in params) {
    if (data[params[key]] && data[params[key]] !== 0) {
      props.question.value[index][key] = data[params[key]];
    }
  }
};

//联级组件
const cascaderChange = (value: any, selectedOptions: any, propsComp: any) => {
  const { column }:any = propsComp;
  if (typeof column.state?.changeWithMethod === 'function') {
    column.state.changeWithMethod(value, selectedOptions, propsComp, props);
  }
}

const serveEvent = (value, column, index) => {
  deleteRule(column.key, index);
  proxy.$NotificationFormSub.pushParams({
    key: CUSTOMEVENTSERVE,
    value: {
      key: column.key,
      value,
      name: column?.name || column?.state?.name || '',
      index
    }
  });
};

//去掉对应的校验
const deleteRule = (key, index) => {
  if (ruleHint.value && ruleHint.value[index]) {
    const indexToRemove = ruleHint.value[index].indexOf(key);
    if (indexToRemove !== -1) {
      ruleHint.value[index].splice(indexToRemove, 1);
    }
  }
};

//校验,是否为空或者正则
const submitVerify = () => {
  ruleHint.value = {};
  let ruleRequired = props.question.state.columns.filter((res) => res.required && !res.hidden);
  let ruleReg = props.question.state.columns.filter((res) => res.reg && !res.hidden);
  let isAgeValid = true;
  let isRuleReg = true;
  if (ruleRequired && ruleRequired.length) {
    ruleRequired.forEach((item) => {
      props.question.value.forEach((res, index) => {
        if (res[item.key] === '' || res[item.key] === null || res[item.key] === undefined) {
          isAgeValid = false;
          if (ruleHint.value[index]) {
            ruleHint.value[index].push(item.key);
          } else {
            ruleHint.value[index] = [item.key];
          }
        }
      });
    });
  }
  if (ruleReg && ruleReg.length) {
    ruleReg.forEach((item) => {
      props.question.value.forEach((res, index) => {
        console.log('正则', item);
        if (!item.reg.test(res[item.key] + '')) {
          isRuleReg = false;
          if (ruleHint.value[index]) {
            ruleHint.value[index].push(item.key);
          } else {
            ruleHint.value[index] = [item.key];
          }
        }
      });
    });
  }

  return isAgeValid && isRuleReg ? true : false;
};

// 是否禁用
const isDisabled = (config, data) => {
  let disabled: boolean = false;
  if (Array.isArray(config)) {
    disabled = isHidden(data, { showKey: config });
  } else if (typeof config === 'boolean') {
    return config;
  }
  return disabled;
};

//组件对外公开方法
defineExpose({
  submitVerify, //验证
  screenValue,
  setColumns,
  key: props.question.key
});
</script>

<style lang="less" scoped>
@import url('./input-customTable.component.less');
</style>
